package k2platform.common.util;

import com.k2data.platform.common.utils.http.RequestException;
import com.k2data.platform.common.utils.http.Requests;
import com.k2data.platform.common.utils.http.SimpleHttpResponse;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by jiangmian on 17-3-6.
 */
public class AssetServiceUtils {
    private static final Logger LOG = LoggerFactory.getLogger(AssetServiceUtils.class);
    private static int SECCEED_RETURN_CODE = 200;
    private static int ID_REGISTER_RETURN_CODE = 201;


    //http://10.1.235.3:8081/data-service/v2/assets
    //

    /**
     * aready exists or add success return true
     * @param url sdmApiUrl
     * @param fieldGroupId fieldGroupID
     * @param name asset name
     * @param compoundId compound id
     * @param description
     * @return
     */
    public static int addAsset(String url, String fieldGroupId, String name, Map<String, String> compoundId,
                               String description){
        StringBuilder requestUrl = new StringBuilder();
        requestUrl.append(url);
        requestUrl.append("/assets");
        SimpleHttpResponse response = null;
        int retryTime = 1;

        Map<String, String> HEADER = new HashMap<>();
        HEADER.put("Accept", "application/json");
        HEADER.put("Content-Type", "application/json");

        Map<String, Object> asset = new HashMap<>();
        asset.put("name", name);
        asset.put("fieldGroupId", fieldGroupId);
        if (description != null) {
            asset.put("description", description);
        }
        asset.put("compoundId", compoundId);
        asset.put("attributes", new ArrayList());
        asset.put("tags", new ArrayList());

        while(response == null || response.getStatusCode() != ID_REGISTER_RETURN_CODE) {
            try {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Add asset: RequestUrl:{}, HEADER:{}.", requestUrl.toString(), HEADER);
                }
                response = Requests.post(requestUrl.toString(), HEADER, (new JSONObject(asset)).toString());
            } catch (RequestException e) {
                LOG.error("Exception when add asset: fieldGroupId:"+fieldGroupId+"; compoundId:{"+compoundId+"}"+e.getMessage());
                e.printStackTrace();
            }

            if(response != null && response.getStatusCode() == ID_REGISTER_RETURN_CODE) {
                //LOG.info("Succeed to add asset: fieldGroupId:"+fieldGroupId+"; compoundId:{"+compoundId+"} retryTime:"+retryTime);
                return ID_REGISTER_RETURN_CODE;
            } else if(response != null && response.getStatusCode() == 409 && response.getText().indexOf("already exists")>0){
                //LOG.error("alreay exits asset: fieldGroupId:"+fieldGroupId+"; compoundId:{"+compoundId+"} retryTime:"+retryTime);
                return 409;
            } else {
                //LOG.error("Fail to add asset: fieldGroupId:"+fieldGroupId+"; compoundId:{"+compoundId+"} retryTime:"+retryTime);
            }

            ++retryTime;
            if(retryTime > 5) {
                break;
            }
        }

        LOG.error("Fail to add asset: fieldGroupId:"+fieldGroupId+"; compoundId:{"+compoundId+"} retryTime:"+retryTime);
        return 400;
    }

    //http://10.1.235.3:8081/data-service/v2/assets?fieldGroupId=huineng_t1&select=*&order=desc-createdAt&pageSize=20&page=1
    //http://10.1.235.3:8081/data-service/v2/assets?fieldGroupId=huineng_t1&select=*
    public static List<Map<String, String>> getAllAsset(String url, String fieldGroupId){

        StringBuilder requestUrl = new StringBuilder();
        requestUrl.append(url);
        requestUrl.append("/assets?");
        if (fieldGroupId == null) {
            requestUrl.append("select=*");
        } else {
            requestUrl.append("fieldGroupId=");
            requestUrl.append(fieldGroupId);
            requestUrl.append("&select=*");
        }

        SimpleHttpResponse response = null;
        int retryTime = 1;

        Map<String, String> HEADER = new HashMap();
        HEADER.put("Accept", "application/json");
        HEADER.put("Content-Type", "application/json");

        while (response == null || response.getStatusCode() != SECCEED_RETURN_CODE) {
            try {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("GetAllAssets: RequestUrl:{}, HEADER:{}.", requestUrl.toString(), HEADER);
                }
                response = Requests.get(requestUrl.toString(), HEADER);
            } catch (RequestException e) {
                LOG.error("Exception when add asset: fieldGroupId:" + fieldGroupId + ";" + e.getMessage());
            }

            if (response != null && response.getStatusCode() == SECCEED_RETURN_CODE) {
                LOG.info("Succeed to add asset: fieldGroupId:" + fieldGroupId + "; retryTime:" + retryTime);
                return resAllCompundId(response.getText());
            } else {
                LOG.error("Fail to add asset: fieldGroupId:" + fieldGroupId + "; retryTime:" + retryTime);
            }

            ++retryTime;
            if (retryTime > 5) {
                break;
            }
        }

        LOG.error("Fail to get asset: fieldGroupId:"+fieldGroupId+"; retryTime:"+retryTime);
        return null;
    }

    private static List<Map<String, String>> resAllCompundId(String json){
        ObjectMapper mapper = new ObjectMapper();
        try {
            Map<String, Object> res = mapper.readValue(json, HashMap.class);
            if(res == null){
                return new ArrayList<>();
            }

            List<Map<String,Object>> assets = (List<Map<String,Object>>)res.get("assets");
            if(assets == null || assets.size() == 0){
                return new ArrayList<>();
            }

            List<Map<String, String>> cmpIds = new ArrayList<>();
            for(Map<String,Object> asset : assets){
                Map<String, String> cmpIdMap = (Map<String, String>) asset.get("compoundId");
                //String cmpId = (new JSONObject(cmpIdMap)).toString();
                cmpIds.add(cmpIdMap);
            }

            LOG.info("cmpIdsNum:"+cmpIds.size());
            return cmpIds;
        }catch (IOException e){
            LOG.error("getProgramParams parse failed!");
        }
        return null;
    }

}
